package com.letoken.platform.admin.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.letoken.platform.admin.enums.*;
import com.letoken.platform.pub.constant.ConstantsValue;
import com.letoken.platform.pub.constant.RedisKeyConstant;
import com.letoken.platform.pub.enums.*;
import com.letoken.platform.pub.exception.ApiServiceException;
import com.letoken.platform.pub.req.PageData;
import com.letoken.platform.repo.app.dao.AppUserAssetsHistoryMapper;
import com.letoken.platform.repo.app.dao.AppUserTeamMapper;
import com.letoken.platform.repo.app.dao.AppUserWalletMapper;
import com.letoken.platform.repo.app.po.AppUserAssetsHistory;
import com.letoken.platform.repo.app.po.AppUserTeam;
import com.letoken.platform.repo.app.po.AppUserWallet;
import com.letoken.platform.repo.ecommerce.dao.*;
import com.letoken.platform.repo.ecommerce.dto.*;
import com.letoken.platform.repo.ecommerce.po.*;
import com.letoken.platform.repo.ecommerce.vo.OrderRes;
import com.letoken.platform.repo.mall.dao.AppConsumerHistoryMapper;
import com.letoken.platform.repo.mall.dao.AppMallAccountMapper;
import com.letoken.platform.repo.mall.dao.AppMallInfoMapper;
import com.letoken.platform.repo.mall.po.AppConsumerHistory;
import com.letoken.platform.repo.mall.po.AppMallAccount;
import com.letoken.platform.repo.mall.po.AppMallInfo;
import com.letoken.platform.repo.mq.constant.EcommerceConstant;
import com.letoken.platform.repo.utlis.PageDataUtil;
import com.letoken.platform.repo.utlis.UniqueIDUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class StoreServiceImpl {

    @Resource
    private AppMallInfoMapper appMallInfoMapper;

    @Resource
    private EcommerceProductMapper ecommerceProductMapper;

    @Resource
    private EcommerceUserOrderMapper ecommerceUserOrderMapper;

    @Resource
    private EcommerceAfterOrderMapper ecommerceAfterOrderMapper;

    @Resource
    private EcommerceUserMasterOrderMapper ecommerceUserMasterOrderMapper;

    @Resource
    private AppMallAccountMapper appMallAccountMapper;

    @Resource
    private EcommerceUserAddressMapper ecommerceUserAddressMapper;

    @Resource
    private AppUserWalletMapper appUserWalletMapper;


    @Resource
    private AppUserTeamMapper appUserTeamMapper;

    @Resource
    private AppUserAssetsHistoryMapper appUserAssetsHistoryMapper;
    @Resource
    private EcommerceFreezeHistoryMapper ecommerceFreezeHistoryMapper;
    @Resource
    private AppConsumerHistoryMapper appConsumerHistoryMapper;

    @Resource
    private EcommerceProductSkuMapper ecommerceProductSkuMapper;

    @Resource
    private EcommerceOrderDetailMapper ecommerceOrderDetailMapper;

    @Resource
    private RabbitTemplate rabbitTemplate;


    @Resource
    private StringRedisTemplate stringRedisTemplate;


    public PageData orders(UserOrderReq req) {

        Page<OrderRes> resPage = ecommerceUserOrderMapper.orders(new Page<>(req.getPageReq().getPage(), req.getPageReq().getSize()), req);
        for (OrderRes record : resPage.getRecords()) {
            record.setProducts(ecommerceUserOrderMapper.orderProducts(record.getOrderNo()));
        }
        return PageDataUtil.getPageData(resPage);
    }


    public void cancelOrder(UserOrderConfirmReq req) {
        EcommerceUserMasterOrder userOrder = getOrderById(req.getId(), EnumOrderStatus.STATUS_0, req.getUserId());
        if (ObjectUtils.isNotEmpty(userOrder)) {
            // 订单关闭
            EcommerceUserMasterOrder updateOrder = new EcommerceUserMasterOrder();
            updateOrder.setId(req.getId());
            updateOrder.setStatus(EnumOrderStatus.STATUS_4.getCode());
            ecommerceUserMasterOrderMapper.updateById(updateOrder);

            List<EcommerceUserOrder> orders = ecommerceUserMasterOrderMapper.subOrders(userOrder.getFatherNo());
            for (EcommerceUserOrder o : orders) {
                cancel(o);
            }
        }
    }

    public EcommerceUserMasterOrder getOrderById(Integer id, EnumOrderStatus enumOrderStatus, Integer userId) {
        EcommerceUserMasterOrder order = ecommerceUserMasterOrderMapper.selectForUpdate(id);
        if (order == null || ConstantsValue.I_1.equals(order.getDeleteStatus())) {
            throw new ApiServiceException(LetokenApiResponseEnum.ERROR_SHOP_RESPONSE_023);
        } else if (enumOrderStatus != null && !enumOrderStatus.getCode().equals(order.getStatus())) {
            throw new ApiServiceException(LetokenApiResponseEnum.ERROR_SHOP_RESPONSE_023);
        }
        if (userId != null) {
            if (!order.getUserId().equals(userId)) {
                log.info("order{}数据不属于用户{}", order.getId(), userId);
                throw new ApiServiceException(LetokenApiResponseEnum.ERROR_SHOP_RESPONSE_023);
            }
        }
        return order;
    }

    public void cancel(EcommerceUserOrder order) {
        EcommerceUserOrder userOrder = getOrder(order.getId(), EnumOrderStatus.STATUS_0, order.getUserId());
        if (ObjectUtils.isNotEmpty(userOrder)) {
            // 订单关闭
            EcommerceUserOrder updateOrder = new EcommerceUserOrder();
            updateOrder.setId(order.getId());
            updateOrder.setStatus(EnumOrderStatus.STATUS_4.getCode());
            ecommerceUserOrderMapper.updateById(updateOrder);

        }
    }

    public EcommerceUserOrder getOrder(Integer orderId, EnumOrderStatus enumOrderStatus, Integer userId) {
        EcommerceUserOrder order = ecommerceUserOrderMapper.selectForUpdate(orderId);
        if (order == null || ConstantsValue.I_1.equals(order.getDeleteStatus())) {
            throw new ApiServiceException(LetokenApiResponseEnum.ERROR_SHOP_RESPONSE_023);
        } else if (enumOrderStatus != null && !enumOrderStatus.getCode().equals(order.getStatus())) {
            throw new ApiServiceException(LetokenApiResponseEnum.ERROR_SHOP_RESPONSE_023);
        }
        if (userId != null) {
            if (!order.getUserId().equals(userId)) {
                log.info("order{}数据不属于用户{}", order.getId(), userId);
                throw new ApiServiceException(LetokenApiResponseEnum.ERROR_SHOP_RESPONSE_023);
            }
        }
        return order;
    }


    public void afterSaleOrdersAudit(ShopAfterOrderApproveReq approveReq) {
//        Integer userId = approveReq.getUserId();
//        AppMallInfo ami =  checkoutShop(approveReq, null, ShopStateEnum.PASS.getCode());


        EcommerceAfterOrder eao = ecommerceAfterOrderMapper.selectById(approveReq.getId());
        if (ObjectUtils.isEmpty(eao)) {
            throw new ApiServiceException(LetokenApiResponseEnum.ERROR_SHOP_RESPONSE_001);
        }
        EcommerceUserOrder order = ecommerceUserOrderMapper.selectById(eao.getOrderId());
        if (ObjectUtils.isEmpty(order)) {
            throw new ApiServiceException(LetokenApiResponseEnum.ERROR_SHOP_RESPONSE_023);
        }

        approveReq.setUserId(eao.getUserId());

        AppMallInfo appMallInfo =  checkoutShop(null, order.getMallId(), ShopStateEnum.PASS.getCode());

//        AppMallInfo appMallInfo = appMallInfoMapper.selectById(order.getMallId());

        EnumRefundType ert = EnumRefundType.getInstance(eao.getType());
        EnumAfterOrderStatus eaos = EnumAfterOrderStatus.getInstance(eao.getStatus());
        if (!eaos.equals(EnumAfterOrderStatus.STATUS_0) && !eaos.equals(EnumAfterOrderStatus.STATUS_1)) {
            throw new ApiServiceException(LetokenApiResponseEnum.ERROR_MALL_SMS_013);
        }
        log.info("售后订单审核:{} {}", approveReq.getUserId(), JSON.toJSONString(approveReq));
        // 审核失败
        if (ConstantsValue.I_2.equals(approveReq.getStatus())) {
            EcommerceAfterOrder updateEao = new EcommerceAfterOrder();
            updateEao.setId(eao.getId());
            updateEao.setStatus(EnumAfterOrderStatus.STATUS_2.getCode());
            updateEao.setApproveReason(approveReq.getApproveReason());
            if (ert.equals(EnumRefundType.STATUS_1)) {
                updateEao.setRefundStatus(3);
            }   else {
                updateEao.setRefundGoodsStatus(5);
            }
            ecommerceAfterOrderMapper.updateById(updateEao);
            return;
        }
        boolean last = null == ecommerceUserMasterOrderMapper.isLast(order.getFatherNo(), order.getId());
        // 直接退款
        if (ert.equals(EnumRefundType.STATUS_1)) {
            doRefund(eao, appMallInfo.getUserId(), order, last);
        } else if (EnumRefundType.STATUS_2.equals(ert)) {
            if (Objects.equals(EnumRefundAmountStatus.STATUS_1.getCode(), eao.getRefundStatus())) {
                doRefund(eao, appMallInfo.getUserId(), order, last);
            } else {
                EcommerceUserAddress userAddress = ecommerceUserAddressMapper.selectShopDefaultAddress(appMallInfo.getUserId());
                EcommerceAfterOrder ueao = new EcommerceAfterOrder();
                ueao.setId(eao.getId());
                ueao.setRefundStatus(EnumRefundAmountStatus.STATUS_1.getCode());
                ueao.setStatus(EnumAfterOrderStatus.STATUS_1.getCode());
                ueao.setRefundGoodsStatus(EnumRefundGoodsStatus.STATUS_1.getCode());
                ueao.setReceiverPhone(userAddress.getPhoneNumber());
                ueao.setReceiverProvince(userAddress.getProvince());
                ueao.setReceiverCity(userAddress.getCity());
                ueao.setReceiverRegion(userAddress.getRegion());
                ueao.setReceiverName(userAddress.getName());
                ueao.setReceiverAddress(userAddress.getDetailAddress());
                ueao.setApproveReason(approveReq.getApproveReason());
                ecommerceAfterOrderMapper.updateById(ueao);
            }
        }
    }

    public void doRefund(EcommerceAfterOrder eao, Integer userId, EcommerceUserOrder order, boolean last) {


        RefundDto dto = new RefundDto(eao.getOrderId(), eao.getId(), userId, eao.getRefundAmount(), eao.getUserId(), false, order.getPayAmount(), order.getContributing(), order.getOrderNo(), order.getShipping(), last);
        Integer accountId = appMallAccountMapper.selectByUserId(dto.getUserId());
        Integer walletId = appUserWalletMapper.checkoutTokenIdAndUserId(LetokenTokenTypeEnum.LET.getId(), dto.getToUserId());
        if (ObjectUtils.isEmpty(accountId) || ObjectUtils.isEmpty(walletId)) {
            throw new ApiServiceException(LetokenApiResponseEnum.ERROR_MALL_SMS_051);
        }
        dto.setAccountId(accountId);
        dto.setWalletId(walletId);


        AppUserWallet w = appUserWalletMapper.selectForUpdate(dto.getWalletId());
        AppMallAccount b = appMallAccountMapper.selectForUpdate(dto.getAccountId());
        if (w.getAvailableBalance().compareTo(BigDecimal.ZERO) < 0) {
            throw new ApiServiceException(LetokenApiResponseEnum.ERROR_MALL_SMS_052);
        }
        if (b.getFreeze().compareTo(dto.getAmount()) < 0 || b.getBalance().compareTo(BigDecimal.ZERO) < 0) {
            throw new ApiServiceException(LetokenApiResponseEnum.ERROR_MALL_SMS_053);
        }

        // 计算主订单运费
        BigDecimal masterShipping = ecommerceUserMasterOrderMapper.selectShipping(dto.getId());
        if (ObjectUtils.isEmpty(masterShipping)) {
            masterShipping = BigDecimal.ZERO;
        }
        BigDecimal refundUser = BigDecimal.ZERO;
        BigDecimal giveMall = BigDecimal.ZERO;
        // 退给用户
        if (dto.getNeedRefundShipping()) {
            refundUser = masterShipping;
        }
        // 给商家
        else if (dto.getLast()) {
            giveMall = masterShipping;
        }

        AppMallAccount updateB = new AppMallAccount();
        updateB.setId(dto.getAccountId());
        if (dto.getNeedRefundShipping() || dto.getLast()) {

            // 解冻订单金额 包含运费
            updateB.setFreeze(b.getFreeze().subtract(dto.getPayAmount()).subtract(masterShipping));
        } else {
            // 解冻订单金额 包含运费
            updateB.setFreeze(b.getFreeze().subtract(dto.getPayAmount()));
        }


        AppUserWallet updateW = new AppUserWallet();
        updateW.setId(w.getId());
        // 返回退款金额
        updateW.setAvailableBalance(w.getAvailableBalance().add(dto.getAmount()).add(refundUser));
        appUserWalletMapper.updateById(updateW);

        // 用户退款流水 退款金额
        String seqNo = UniqueIDUtils.genSeqNo("RA");
        AppUserAssetsHistory assetHistory = new AppUserAssetsHistory();
        assetHistory.setUserId(dto.getToUserId());
        assetHistory.setType(TokenTransactionTypeEnum.NEW_SHOP_REFUND.getValue());
        assetHistory.setStatus(TokenTransactionStatusEnum.COMPLETED.getValue());
        assetHistory.setTokenId(LetokenTokenTypeEnum.LET.getId());
        assetHistory.setAmount(dto.getAmount().add(refundUser));
        assetHistory.setSn(dto.getOrderNo());
        assetHistory.setBalance(updateW.getAvailableBalance());
        assetHistory.setCreateTime(LocalDateTime.now());
        assetHistory.setUpdateTime(assetHistory.getCreateTime());
        appUserAssetsHistoryMapper.insert(assetHistory);

        // 解冻订单金额
        EcommerceFreezeHistory efh = new EcommerceFreezeHistory();
        efh.setAmount(dto.getPayAmount().negate());
        efh.setBalance(updateB.getFreeze());
        efh.setUserId(b.getUserId());
        efh.setMallId(b.getMallId());
        efh.setType(EnumFreezeType.STATUS_1.getCode());
        efh.setInOut(InOutTypeEnum.OUT.ordinal());
        efh.setSeqNo(seqNo);
        efh.setOrderId(dto.getId());
        efh.setAfterId(dto.getAfterId());
        ecommerceFreezeHistoryMapper.insert(efh);


        // 运费解冻流水  推给用户
        if (refundUser.compareTo(BigDecimal.ZERO) > 0) {
            efh = new EcommerceFreezeHistory();
            efh.setAmount(masterShipping.negate());
            efh.setBalance(updateB.getFreeze());
            efh.setUserId(b.getUserId());
            efh.setMallId(b.getMallId());
            efh.setType(EnumFreezeType.STATUS_3.getCode());
            efh.setInOut(InOutTypeEnum.OUT.ordinal());
            efh.setSeqNo(String.format("%s1", seqNo));
            efh.setOrderId(dto.getId());
            efh.setAfterId(dto.getAfterId());
            ecommerceFreezeHistoryMapper.insert(efh);
        }


        order = new EcommerceUserOrder();
        order.setStatus(EnumOrderStatus.STATUS_4.getCode());
        BigDecimal a = dto.getPayAmount().subtract(dto.getAmount());

        // 减去发行金额 剩余给商家
        BigDecimal receiveAmount = BigDecimal.ZERO;

        if (dto.getContributing().compareTo(BigDecimal.ONE) < 0) {
            receiveAmount = a.subtract(a.multiply(dto.getContributing()));
        }

        if (receiveAmount.compareTo(BigDecimal.ZERO) > 0 || giveMall.compareTo(BigDecimal.ZERO) > 0) {

            updateB.setBalance(b.getBalance().add(a).add(giveMall));


            if (a.compareTo(BigDecimal.ZERO) > 0) {
                assetHistory = new AppUserAssetsHistory();
                assetHistory.setUserId(dto.getUserId());
                assetHistory.setType(TokenTransactionTypeEnum.NEW_SHOP_SUCCESS.getValue());
                assetHistory.setStatus(TokenTransactionStatusEnum.COMPLETED.getValue());
                assetHistory.setTokenId(LetokenTokenTypeEnum.LET.getId());
                assetHistory.setAmount(a);
                assetHistory.setSn(dto.getOrderNo());
                assetHistory.setCreateTime(LocalDateTime.now());
                assetHistory.setUpdateTime(assetHistory.getCreateTime());
                appUserAssetsHistoryMapper.insert(assetHistory);
            }

            // 运费解冻 退给商家
            if (giveMall.compareTo(BigDecimal.ZERO) > 0) {
                assetHistory = new AppUserAssetsHistory();
                assetHistory.setUserId(dto.getUserId());
                assetHistory.setType(TokenTransactionTypeEnum.SHIPPING.getValue());
                assetHistory.setStatus(TokenTransactionStatusEnum.COMPLETED.getValue());
                assetHistory.setTokenId(LetokenTokenTypeEnum.LET.getId());
                assetHistory.setAmount(giveMall);
                assetHistory.setSn(dto.getOrderNo() + "SH");
                assetHistory.setCreateTime(LocalDateTime.now());
                assetHistory.setUpdateTime(assetHistory.getCreateTime());
                appUserAssetsHistoryMapper.insert(assetHistory);

                efh = new EcommerceFreezeHistory();
                efh.setAmount(giveMall.negate());
                efh.setBalance(updateB.getFreeze());
                efh.setUserId(b.getUserId());
                efh.setMallId(b.getMallId());
                efh.setType(EnumFreezeType.STATUS_3.getCode());
                efh.setInOut(InOutTypeEnum.OUT.ordinal());
                efh.setSeqNo(String.format("%s1", seqNo));
                efh.setOrderId(dto.getId());
                efh.setAfterId(dto.getAfterId());
                ecommerceFreezeHistoryMapper.insert(efh);

            }

            order.setStatus(EnumOrderStatus.STATUS_3.getCode());
        }

        appMallAccountMapper.updateById(updateB);


        // todo 增加消费建设值
        if (dto.getContributing().compareTo(ConstantsValue.CONSUME_LIMIT_EC_CONTRIBUTING) >= 0) {
            AppUserTeam appUserTeam = appUserTeamMapper.selectForUpdate(dto.getUserId());
            if (ObjectUtils.isNotEmpty(appUserTeam) && a.compareTo(BigDecimal.ZERO) > 0) {
                AppUserTeam newAut = new AppUserTeam();
                newAut.setUserId(appUserTeam.getUserId());
                newAut.setConsumerValue(appUserTeam.getConsumerValue().add(a));
                appUserTeamMapper.updateById(newAut);

                AppConsumerHistory f = new AppConsumerHistory();
                f.setAmount(a);
                f.setUserId(appUserTeam.getUserId());
                f.setBalance(newAut.getConsumerValue());
                f.setSeqNo(dto.getOrderNo());
                f.setType(ConstantsValue.I_1);
                appConsumerHistoryMapper.insert(f);
            }
        }


        // 售后完成
        EcommerceAfterOrder updateEao = new EcommerceAfterOrder();
        updateEao.setId(dto.getAfterId());
        updateEao.setRefundStatus(EnumRefundAmountStatus.STATUS_2.getCode());
        updateEao.setStatus(EnumAfterOrderStatus.STATUS_1.getCode());
        // 商家确认收到退货
        if (dto.getIsRefundGoods()) {
            updateEao.setRefundGoodsStatus(EnumRefundGoodsStatus.STATUS_4.getCode());
        }
        ecommerceAfterOrderMapper.updateById(updateEao);


        // 订单关闭
        order.setId(dto.getId());
        order.setRefundAmount(dto.getAmount());
        ecommerceUserOrderMapper.updateById(order);

        Integer skuId = ecommerceUserOrderMapper.selectSkuIdByOrderId(dto.getId());
        Integer refundQuantity = ecommerceUserOrderMapper.selectSkuIdByAfterOrderId(dto.getAfterId());
        if (ObjectUtils.isNotEmpty(skuId) && ObjectUtils.isNotEmpty(refundQuantity)) {
            EcommerceProductSku productSku = ecommerceProductSkuMapper.selectById(skuId);
            productSku.setStock(productSku.getStock() + refundQuantity);
            // 后加销量
            Integer quantity = ecommerceUserOrderMapper.selectOrderQuantity(dto.getId());
            if (quantity != null && quantity > refundQuantity) {
                productSku.setSale(productSku.getSale() + (quantity - refundQuantity));
            }
            ecommerceProductSkuMapper.updateById(productSku);
        }

        if (a.compareTo(BigDecimal.ZERO) > 0 && a.compareTo(dto.getShipping()) > 0) {
            EcommerceIssue ecommerceIssue = new EcommerceIssue();
            ecommerceIssue.setContributing(dto.getContributing());
            ecommerceIssue.setOrderAmount(a.subtract(dto.getShipping()));
            ecommerceIssue.setOrderId(dto.getId());
            ecommerceIssue.setUserId(dto.getToUserId());
            ecommerceIssue.setMallUserId(dto.getUserId());
            rabbitTemplate.convertAndSend(EcommerceConstant.exchange, EcommerceConstant.queue, JSONObject.toJSON(ecommerceIssue).toString());
        }
    }


    public AppMallInfo checkoutShop(Integer userId, Integer mallId, Integer status) {
        if (ObjectUtils.isNotEmpty(userId)) {
            final String key = String.format(RedisKeyConstant.ECOMMERCE_SHOP_INFO, userId);
            if (Boolean.TRUE.equals(stringRedisTemplate.hasKey(key))) {
                String re = stringRedisTemplate.opsForValue().get(key);
                if (ObjectUtils.isNotEmpty(re)) {
                    return JSONObject.parseObject(re, AppMallInfo.class);
                }
            }
        }


        LambdaQueryWrapper<AppMallInfo> lqwami = new LambdaQueryWrapper<>();
        if (ObjectUtils.isNotEmpty(mallId)) {
            lqwami.eq(AppMallInfo::getId, mallId);
        }
        if (ObjectUtils.isNotEmpty(userId)) {
            lqwami.eq(AppMallInfo::getUserId, userId);
        }
        if (ObjectUtils.isNotEmpty(status)) {
            lqwami.eq(AppMallInfo::getState, status);
        }
        lqwami.orderByDesc(AppMallInfo::getId).last("limit 1");

        AppMallInfo appMallInfo;
        if (ObjectUtils.isEmpty((appMallInfo = appMallInfoMapper.selectOne(lqwami)))) {
            throw new ApiServiceException(LetokenApiResponseEnum.ERROR_MALL_SMS_011);
        }
        if (null == appMallAccountMapper.haveBond(appMallInfo.getId())) {
            throw new ApiServiceException(LetokenApiResponseEnum.ERROR_SHOP_RESPONSE_034);
        }

        if (ObjectUtils.isNotEmpty(userId)) {
            final String key = String.format(RedisKeyConstant.ECOMMERCE_SHOP_INFO, userId);
            // 缓存12小时
            stringRedisTemplate.opsForValue().set(key, JSON.toJSONString(appMallInfo), 12, TimeUnit.HOURS);
        }
        return appMallInfo;
    }


    //确认收货
    public void orderConfirmReceipt(UserOrderConfirmReq req) {

        Integer userId = req.getUserId();
        EcommerceUserMasterOrder masterOrder = getOrderById(req.getId(), EnumOrderStatus.STATUS_2, userId);
        AppMallInfo ami = checkoutShop(null, masterOrder.getMallId(), null);

        List<EcommerceUserOrder> list = ecommerceUserOrderMapper.selectConfirmByFatherNo(masterOrder.getFatherNo());

        Integer accountId = null;
        for (EcommerceUserOrder order : list) {
            // 存在进行中的售后订单
            if (ecommerceAfterOrderMapper.existsRunningAfterOrder(order.getId()) > 0) {
                LambdaQueryWrapper<EcommerceAfterOrder> after = new LambdaQueryWrapper<>();
                after.eq(EcommerceAfterOrder::getOrderId, order.getId())
                        .ne(EcommerceAfterOrder::getStatus, EnumAfterOrderStatus.STATUS_3.getCode())
                        .orderByDesc(EcommerceAfterOrder::getCreateTime)
                        .last(" limit 1 ");
                EcommerceAfterOrder afterOrder = ecommerceAfterOrderMapper.selectOne(after);
                if (ObjectUtils.isNotEmpty(afterOrder)) {
                        EcommerceAfterOrder afo = new EcommerceAfterOrder();
                        afo.setId(afterOrder.getId());
                        afo.setStatus(EnumAfterOrderStatus.STATUS_3.getCode());
                        ecommerceAfterOrderMapper.updateById(afo);
                }
            }

            EcommerceIssue ecommerceIssue = new EcommerceIssue();
            ecommerceIssue.setContributing(order.getContributing());
            ecommerceIssue.setOrderAmount(order.getPayAmount());
            ecommerceIssue.setOrderId(order.getId());
            ecommerceIssue.setUserId(order.getUserId());
            ecommerceIssue.setMallUserId(ami.getUserId());

            // 减去发行金额 剩余给商家
            BigDecimal receiveAmount = BigDecimal.ZERO;

           /* if (order.getContributing().compareTo(BigDecimal.ONE) < 0) {
                receiveAmount = ecommerceIssue.getOrderAmount().subtract(ecommerceIssue.getOrderAmount().multiply(order.getContributing()));
            }*/

            if (order.getContributing().compareTo(BigDecimal.ONE) < 0){
                if(order.getPayAmountCap().compareTo(BigDecimal.ZERO)>0 && order.getPayAmountCap() != null){
                    receiveAmount  = order.getPayAmountCap().subtract(order.getPayAmountCap().multiply(order.getContributing()));
                }else {
                    receiveAmount  = ecommerceIssue.getOrderAmount().subtract(ecommerceIssue.getOrderAmount().multiply(order.getContributing()));
                }
            }

            //FinishDto dto = new FinishDto(order.getId(), ami.getUserId(), ami.getUserId(), order.getPayAmount(), receiveAmount);
            FinishDto dto =  new FinishDto(order.getId(),ami.getUserId(),ami.getUserId(),order.getPayAmountCap().compareTo(BigDecimal.ZERO)>0?order.getPayAmountCap():order.getPayAmount(),receiveAmount,order.getPayAmountCap().compareTo(BigDecimal.ZERO)>0?2:1);

            accountId = appMallAccountMapper.selectByUserId(dto.getUserId());
            if (ObjectUtils.isEmpty(accountId)) {
                throw new ApiServiceException(LetokenApiResponseEnum.ERROR_MALL_SMS_051);
            }

            AppMallAccount b = appMallAccountMapper.selectForUpdate(accountId);
            if (b.getFreeze().compareTo(dto.getAmount()) < 0 || b.getBalance().compareTo(BigDecimal.ZERO) < 0) {
                throw new ApiServiceException(LetokenApiResponseEnum.ERROR_MALL_SMS_053);
            }
            AppMallAccount updateB = new AppMallAccount();
            /*updateB.setId(accountId);
            updateB.setFreeze(b.getFreeze().subtract(dto.getAmount()));
            updateB.setBalance(b.getBalance().add(dto.getReceiveAmount()));
            appMallAccountMapper.updateById(updateB);*/
            if(dto.getPayType().equals(1)){
                if (b.getFreeze().compareTo(dto.getAmount()) < 0 || b.getBalance().compareTo(BigDecimal.ZERO) < 0){
                    throw new ApiServiceException(LetokenApiResponseEnum.ERROR_MALL_SMS_053);
                }
                updateB.setId(accountId);
                updateB.setFreeze(b.getFreeze().subtract(dto.getAmount()));
                updateB.setBalance(b.getBalance().add(dto.getReceiveAmount()));
                appMallAccountMapper.updateById(updateB);
            }else{
                if (b.getFreezeCap().compareTo(dto.getAmount()) < 0 || b.getBalanceCAP().compareTo(BigDecimal.ZERO) < 0){
                    throw new ApiServiceException(LetokenApiResponseEnum.ERROR_MALL_SMS_053);
                }
                updateB.setId(accountId);
                updateB.setFreeze(b.getFreezeCap().subtract(dto.getAmount()));
                updateB.setBalanceCAP(b.getBalance().add(dto.getReceiveAmount()));
                appMallAccountMapper.updateById(updateB);
            }


            EcommerceUserOrder order2 = ecommerceUserOrderMapper.selectById(dto.getId());


            if (dto.getReceiveAmount().compareTo(BigDecimal.ZERO) > 0) {
                AppUserAssetsHistory assetHistory = new AppUserAssetsHistory();
                assetHistory.setUserId(dto.getUserId());
                assetHistory.setType(TokenTransactionTypeEnum.NEW_SHOP_SUCCESS.getValue());
                assetHistory.setStatus(TokenTransactionStatusEnum.COMPLETED.getValue());
                assetHistory.setTokenId(dto.getPayType().equals(1)?LetokenTokenTypeEnum.LET.getId():LetokenTokenTypeEnum.CAP.getId());
                assetHistory.setAmount(dto.getReceiveAmount());
                assetHistory.setSn(order2.getOrderNo());
                assetHistory.setCreateTime(LocalDateTime.now());
                assetHistory.setUpdateTime(assetHistory.getCreateTime());
                appUserAssetsHistoryMapper.insert(assetHistory);
            }

            String seqNo = UniqueIDUtils.genSeqNo("OF");
            EcommerceFreezeHistory efh = new EcommerceFreezeHistory();
            efh.setAmount(dto.getAmount().negate());
            efh.setBalance(updateB.getFreeze());
            efh.setUserId(b.getUserId());
            efh.setMallId(b.getMallId());
            efh.setType(EnumFreezeType.STATUS_2.getCode());
            efh.setInOut(InOutTypeEnum.OUT.ordinal());
            efh.setSeqNo(seqNo);
            efh.setOrderId(dto.getId());
            if(dto.getPayType().equals(2)){
                efh.setAmountCap(dto.getAmount().negate());
            }
            ecommerceFreezeHistoryMapper.insert(efh);

            // 订单完成
            order2 = new EcommerceUserOrder();
            order2.setId(dto.getId());
            order2.setStatus(EnumOrderStatus.STATUS_3.getCode());
            order2.setConfirmStatus(ConstantsValue.I_1);
            ecommerceUserOrderMapper.updateById(order2);
            EcommerceOrderDetail orderDetail = new EcommerceOrderDetail();
            orderDetail.setId(order2.getId());
            orderDetail.setReceiveTime(LocalDateTime.now());
            ecommerceOrderDetailMapper.updateById(orderDetail);

            Integer sku = ecommerceUserOrderMapper.selectSkuIdByOrderId(dto.getId());
            if (ObjectUtils.isNotEmpty(sku)) {
                EcommerceProductSku productSku = ecommerceProductSkuMapper.selectById(sku);
                EcommerceUserOrder userOrder = ecommerceUserOrderMapper.selectById(dto.getId());
                //更新库存
                productSku.setSale(productSku.getSale() + userOrder.getQuantity());
                ecommerceProductSkuMapper.updateById(productSku);
            }
            // todo 增加消费建设值
            if (order.getContributing().compareTo(ConstantsValue.CONSUME_LIMIT_EC_CONTRIBUTING) >= 0) {
                AppUserTeam appUserTeam = appUserTeamMapper.selectForUpdate(order.getUserId());
                if (ObjectUtils.isNotEmpty(appUserTeam)) {
                    AppUserTeam newAut = new AppUserTeam();
                    newAut.setUserId(appUserTeam.getUserId());
                    newAut.setConsumerValue(appUserTeam.getConsumerValue().add(order.getPayAmount()));
                    appUserTeamMapper.updateById(newAut);

                    AppConsumerHistory a = new AppConsumerHistory();
                    a.setAmount(order.getPayAmount());
                    a.setUserId(appUserTeam.getUserId());
                    a.setBalance(newAut.getConsumerValue());
                    a.setSeqNo(order.getOrderNo());
                    a.setType(ConstantsValue.I_1);
                    appConsumerHistoryMapper.insert(a);
                }
            }
            //商城发行
            rabbitTemplate.convertAndSend(EcommerceConstant.exchange, EcommerceConstant.queue, JSONObject.toJSON(ecommerceIssue).toString());
        }
        EcommerceUserMasterOrder updateMasterOrder = new EcommerceUserMasterOrder();
        updateMasterOrder.setId(req.getId());
        updateMasterOrder.setStatus(EnumOrderStatus.STATUS_3.getCode());
        updateMasterOrder.setConfirmStatus(ConstantsValue.I_1);
        updateMasterOrder.setReceiveTime(LocalDateTime.now());
        ecommerceUserMasterOrderMapper.updateById(updateMasterOrder);

        // 解冻运费
        if (ObjectUtils.isNotEmpty(accountId) && ObjectUtils.isNotEmpty(masterOrder.getShipping()) && masterOrder.getShipping().compareTo(BigDecimal.ZERO) > 0) {
            AppMallAccount b = appMallAccountMapper.selectForUpdate(accountId);
            AppMallAccount updateB = new AppMallAccount();
            /*updateB.setId(accountId);
            updateB.setFreeze(b.getFreeze().subtract(masterOrder.getShipping()));
            updateB.setBalance(b.getBalance().add(masterOrder.getShipping()));
            appMallAccountMapper.updateById(updateB);*/
            if(masterOrder.getPayAmountCap().compareTo(BigDecimal.ZERO)>0){
                updateB.setId(accountId);
                updateB.setFreezeCap(b.getFreezeCap().subtract(masterOrder.getShippingCap()));
                updateB.setBalanceCAP(b.getBalanceCAP().add(masterOrder.getShippingCap()));
            }else{
                updateB.setId(accountId);
                updateB.setFreeze(b.getFreeze().subtract(masterOrder.getShipping()));
                updateB.setBalance(b.getBalance().add(masterOrder.getShipping()));
            }


            String seqNo = UniqueIDUtils.genSeqNo("RF");
            EcommerceFreezeHistory efh = new EcommerceFreezeHistory();
            efh.setAmount(masterOrder.getShipping().negate());
            efh.setBalance(updateB.getFreeze());
            efh.setUserId(b.getUserId());
            efh.setMallId(b.getMallId());
            efh.setType(EnumFreezeType.STATUS_5.getCode());
            efh.setInOut(InOutTypeEnum.OUT.ordinal());
            efh.setSeqNo(seqNo);
            efh.setOrderId(req.getId());
            if(masterOrder.getPayAmountCap().compareTo(BigDecimal.ZERO)>0){
                efh.setAmountCap(masterOrder.getShippingCap());
            }
            ecommerceFreezeHistoryMapper.insert(efh);


            AppUserAssetsHistory assetHistory = new AppUserAssetsHistory();
            assetHistory.setUserId(b.getUserId());
            assetHistory.setType(TokenTransactionTypeEnum.SHIPPING.getValue());
            assetHistory.setStatus(TokenTransactionStatusEnum.COMPLETED.getValue());
            assetHistory.setTokenId(LetokenTokenTypeEnum.LET.getId());
            //assetHistory.setAmount(masterOrder.getShipping());
            assetHistory.setTokenId(masterOrder.getPayAmountCap().compareTo(BigDecimal.ZERO)>0?LetokenTokenTypeEnum.CAP.getId():LetokenTokenTypeEnum.LET.getId());
            assetHistory.setAmount(masterOrder.getPayAmountCap().compareTo(BigDecimal.ZERO)>0?masterOrder.getShippingCap():masterOrder.getShipping());
            assetHistory.setSn(seqNo);
            assetHistory.setCreateTime(LocalDateTime.now());
            assetHistory.setUpdateTime(assetHistory.getCreateTime());
            appUserAssetsHistoryMapper.insert(assetHistory);

        }
    }


}
